package collectionFrame;


import java.util.*;

public class Demo3_Generics {

    public static void main(String[] args) {

        new GenericsClass<String,Integer,Double>("hello",12345,3.1415).outputClass();

        //匿名内部类实现泛型接口
        GenericsInterface<Boolean, String> genericsInterface = new GenericsInterface<Boolean, String>() {
            @Override
            public void getValue(Boolean value) {
                System.out.println("第一个泛型：" + value.getClass());
            }

            @Override
            public void getValueOther(String value) {
                System.out.println("第二个泛型：" + value.getClass());
            }
        };

        genericsInterface.getValue(false);
        genericsInterface.getValueOther("hello");

        System.out.println("===========================================");

        new GenericsMethod().genMethod("hello",3.14);
        new GenericsMethod().genMethod(12345,true);

        System.out.println("===========================================");

        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");
        new IteratorCollection().showAllElement(list);

    }

}

/**
 * 在普通类的基础上，在类名的后面加上<通用的类型标识>，就变成了泛型类
 * 类中的参数化类型可以同时定义多个
 * @param <T>
 */
class GenericsClass<T,T1,T2>{

    private T t;
    private T1 t1;
    private T2 t2;

    public GenericsClass(T t, T1 t1, T2 t2) {
        this.t = t;
        this.t1 = t1;
        this.t2 = t2;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    public T1 getT1() {
        return t1;
    }

    public void setT1(T1 t1) {
        this.t1 = t1;
    }

    public T2 getT2() {
        return t2;
    }

    public void setT2(T2 t2) {
        this.t2 = t2;
    }

    public void outputClass(){
        System.out.println(this.t.getClass());
        System.out.println(this.t1.getClass());
        System.out.println(this.t2.getClass());
        System.out.println("==============================");
    }

}

/**
 * 在普通接口的基础上，在接口名的后面加上<通用的类型标识>，就变成了泛型接口
 * 接口中的泛型由子类继承的时候会根据自定定义的泛型确定子类方法中参数的类型
 * @param <T>
 */
interface GenericsInterface<T,T1>{

    void getValue(T value);

    void getValueOther(T1 value);

}

/**
 * 在一个普通类中创建泛型方法
 */
class GenericsMethod{

    /**
     * 在普通方法的基础上，在返回值前面一定要加上 <通用的类型标识> 来声明当前方法为泛型方法
     * 泛型方法也可以有多个泛型
     * @param <T> 声明此方法为泛型方法，必须存在
     * @param t 方法中的参数是泛型T类型的，不是必须
     * @return 按照泛型的类型返回，不是必须
     */
    public <T,T1> T genMethod(T t,T1 t1){
        System.out.println(t+"的类型是"+t.getClass()+";"+t1+"的类型是"+t1.getClass());
        return t;
    }

}

class IteratorCollection{
    public void showAllElement(Collection<? extends String> coll){
        Iterator<? extends String> iterator = coll.iterator();
        while(iterator.hasNext()) {
            String next = iterator.next();
            System.out.println(next);
        }
    }
}

